package jj.tt.dd;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理模式
 */
public class TestProxy {
    public static void main(String[] args) {
        //都是先创建被代理类的实例对象
        RealSubject realSubject = new RealSubject();
        //创建一个实现了InvocationHandler 接口的类的对象;
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
        //调用 blind 方法.动态的返回一个跟realSubject 实现同样接口的代理类对象
        Object obj = myInvocationHandler.blind(realSubject);
        //进行强转
        Subject subject = (Subject) obj;//此时的subject 就是代理类的对象
        //执行该方法,就会转到 invoke 方法的调用;
        // 那么就是说执行的结果就是被代理类中抽象方法的的执行结果
        subject.action();

        NikeCloth nikeCloth = new NikeCloth();
        nikeCloth.productCloth();
        ClothFactory clothFactory = (ClothFactory) myInvocationHandler.blind(nikeCloth);
        clothFactory.productCloth();

    }
}

interface Subject {
    void action();
}

//被代理类
class RealSubject implements Subject {

    @Override
    public void action() {
        System.out.println("我是被代理类,是真实的,");
    }
}

//动态代理相关的一个接口 InvocationHandler
//代理类
class MyInvocationHandler implements InvocationHandler {
    Object obj;//实现了接口的被代理类的对象的声明

    //1. 给被代理类的对象实例化,
    //2. 返回一个代理类的对象 this
    public Object blind(Object obj) {
        this.obj = obj;
        //参数: classLoader : 被代理类
        //     interfaces:  代理类也要实现的接口
        //     this: 返回一个代理对象
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), this);
    }


    //每当调用 invoke 的时候,就是调用的被代理类中的 action (抽象)方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //method 方法的返回值是 returnValue
        Object returnValue = method.invoke(obj, args);
        return returnValue;
    }
}